using System;
using dnAnalytics.Statistics.Distributions;
using NUnit.Framework;

namespace dnAnalytics.Tests.Statistics.Distributions
{
    [TestFixture]
    public class GeometricTests
    {
        private const double mAcceptableError = 1e-12;

        [Test]
        public void Geometric()
        {
            Geometric geo = new Geometric(0.7);

            Assert.AreEqual(1.0 / 0.7, geo.Mean, mAcceptableError);
            Assert.AreEqual(System.Math.Sqrt((1.0 - 0.7) / (0.7 * 0.7)), geo.StdDev, mAcceptableError);
            Assert.AreEqual((1.0 - 0.7) / (0.7 * 0.7), geo.Variance, mAcceptableError);
            Assert.AreEqual(1, geo.Mode, mAcceptableError);
            Assert.AreEqual(1, geo.Median, mAcceptableError);
            Assert.AreEqual(1.258986998900990, geo.Entropy, mAcceptableError);

            // Test the PDF.
            Assert.AreEqual(0.0, geo.Probability(0), mAcceptableError);
            Assert.AreEqual(0.7, geo.Probability(1), mAcceptableError);
            Assert.AreEqual(System.Math.Pow(0.3, 4) * 0.7, geo.Probability(5), mAcceptableError);
            Assert.AreEqual(System.Math.Pow(0.3, 14) * 0.7, geo.Probability(15), mAcceptableError);

            // Test the CDF.
            Assert.AreEqual(0.0, geo.CumulativeDistribution(0), mAcceptableError);
            Assert.AreEqual(0.7, geo.CumulativeDistribution(1), mAcceptableError);
            Assert.AreEqual(1.0 - System.Math.Pow(0.3, 5), geo.CumulativeDistribution(5), mAcceptableError);
            Assert.AreEqual(1.0 - System.Math.Pow(0.3, 15), geo.CumulativeDistribution(15), mAcceptableError);
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void GeometricConstructorFail()
        {
            Geometric geo = new Geometric(-0.1);
        }

        [Test]
        public void GetSetRNG()
        {
            Geometric geo = new Geometric(0.7);

            // Try getting the random number generator.
            System.Random rnd = geo.RandomNumberGenerator;
            // Try setting the random number generator.
            geo.RandomNumberGenerator = new System.Random();
        }
    }
}